/**
 * Version Manager - 版本管理系统
 * 基于 AI Writer Lite 的实现，为 IntelliMark 提供版本控制和回滚功能
 */

import Store from 'electron-store'
import { v4 as uuidv4 } from 'uuid'

export interface VersionMetadata {
  id: string
  timestamp: number
  operation: 'ai_polish' | 'ai_expand' | 'ai_translate' | 'ai_fix_grammar' | 'ai_change_tone' | 'ai_summarize' | 'ai_continue' | 'manual_save'
  reason?: string
  selectionRange?: {
    start: number
    end: number
  }
  provider?: string
  model?: string
  tokensUsed?: number
  cost?: number
}

export interface DocumentVersion {
  id: string
  content: string
  metadata: VersionMetadata
  checksum: string
}

export interface VersionHistory {
  documentId: string
  versions: DocumentVersion[]
  currentVersion: string
  maxVersions: number
  autoSave: boolean
}

export class VersionManager {
  private store: Store
  private maxVersionsPerDocument: number = 50
  private compressionThreshold: number = 20

  constructor() {
    this.store = new Store({
      name: 'version-history',
      defaults: {
        histories: {},
        settings: {
          maxVersionsPerDocument: 50,
          autoSave: true,
          compressionThreshold: 20
        }
      }
    })
  }

  /**
   * 创建新版本
   */
  public createVersion(
    documentId: string,
    content: string,
    operation: VersionMetadata['operation'],
    options: {
      reason?: string
      selectionRange?: { start: number; end: number }
      provider?: string
      model?: string
      tokensUsed?: number
      cost?: number
    } = {}
  ): string {
    const versionId = uuidv4()
    const timestamp = Date.now()

    const metadata: VersionMetadata = {
      id: versionId,
      timestamp,
      operation,
      ...options
    }

    const version: DocumentVersion = {
      id: versionId,
      content,
      metadata,
      checksum: this.calculateChecksum(content)
    }

    const history = this.getDocumentHistory(documentId)

    // 添加新版本
    history.versions.push(version)
    history.currentVersion = versionId

    // 清理旧版本
    this.cleanupOldVersions(history)

    // 保存更新后的历史
    this.store.set(`histories.${documentId}`, history)

    console.log(`Created version ${versionId} for document ${documentId}`)
    return versionId
  }

  /**
   * 获取文档版本历史
   */
  public getDocumentHistory(documentId: string): VersionHistory {
    const history = this.store.get(`histories.${documentId}`) as VersionHistory

    if (!history) {
      const newHistory: VersionHistory = {
        documentId,
        versions: [],
        currentVersion: '',
        maxVersions: this.maxVersionsPerDocument,
        autoSave: true
      }
      this.store.set(`histories.${documentId}`, newHistory)
      return newHistory
    }

    return history
  }

  /**
   * 获取特定版本
   */
  public getVersion(documentId: string, versionId: string): DocumentVersion | null {
    const history = this.getDocumentHistory(documentId)
    return history.versions.find(v => v.id === versionId) || null
  }

  /**
   * 获取当前版本
   */
  public getCurrentVersion(documentId: string): DocumentVersion | null {
    const history = this.getDocumentHistory(documentId)
    return history.versions.find(v => v.id === history.currentVersion) || null
  }

  /**
   * 回滚到指定版本
   */
  public rollbackToVersion(documentId: string, versionId: string): DocumentVersion | null {
    const targetVersion = this.getVersion(documentId, versionId)
    if (!targetVersion) {
      throw new Error(`Version ${versionId} not found for document ${documentId}`)
    }

    const history = this.getDocumentHistory(documentId)
    history.currentVersion = versionId
    this.store.set(`histories.${documentId}`, history)

    console.log(`Rolled back document ${documentId} to version ${versionId}`)
    return targetVersion
  }

  /**
   * 比较两个版本
   */
  public compareVersions(
    documentId: string,
    fromVersionId: string,
    toVersionId: string
  ): {
    from: DocumentVersion | null
    to: DocumentVersion | null
    diff: Array<{
      type: 'add' | 'remove' | 'unchanged'
      content: string
      position: number
    }>
  } | null {
    const fromVersion = this.getVersion(documentId, fromVersionId)
    const toVersion = this.getVersion(documentId, toVersionId)

    if (!fromVersion || !toVersion) {
      return null
    }

    const diff = this.calculateDiff(fromVersion.content, toVersion.content)

    return {
      from: fromVersion,
      to: toVersion,
      diff
    }
  }

  /**
   * 删除版本
   */
  public deleteVersion(documentId: string, versionId: string): boolean {
    const history = this.getDocumentHistory(documentId)
    const versionIndex = history.versions.findIndex(v => v.id === versionId)

    if (versionIndex === -1) {
      return false
    }

    history.versions.splice(versionIndex, 1)

    // 如果删除的是当前版本，设置最新的版本为当前版本
    if (history.currentVersion === versionId) {
      history.currentVersion = history.versions.length > 0
        ? history.versions[history.versions.length - 1].id
        : ''
    }

    this.store.set(`histories.${documentId}`, history)
    console.log(`Deleted version ${versionId} from document ${documentId}`)
    return true
  }

  /**
   * 清理文档历史
   */
  public clearDocumentHistory(documentId: string): void {
    this.store.delete(`histories.${documentId}`)
    console.log(`Cleared history for document ${documentId}`)
  }

  /**
   * 获取所有文档列表
   */
  public getAllDocuments(): string[] {
    const histories = this.store.get('histories') as Record<string, VersionHistory>
    return Object.keys(histories)
  }

  /**
   * 获取统计信息
   */
  public getStatistics(): {
    totalDocuments: number
    totalVersions: number
    totalSize: number
    oldestVersion?: Date
    newestVersion?: Date
  } {
    const histories = this.store.get('histories') as Record<string, VersionHistory>
    const documents = Object.values(histories)

    let totalVersions = 0
    let totalSize = 0
    let oldestTimestamp = Date.now()
    let newestTimestamp = 0

    documents.forEach(history => {
      totalVersions += history.versions.length
      history.versions.forEach(version => {
        totalSize += version.content.length
        oldestTimestamp = Math.min(oldestTimestamp, version.metadata.timestamp)
        newestTimestamp = Math.max(newestTimestamp, version.metadata.timestamp)
      })
    })

    return {
      totalDocuments: documents.length,
      totalVersions,
      totalSize,
      oldestVersion: totalVersions > 0 ? new Date(oldestTimestamp) : undefined,
      newestVersion: totalVersions > 0 ? new Date(newestTimestamp) : undefined
    }
  }

  /**
   * 压缩旧版本
   */
  public compressVersions(documentId: string, keepCount: number = 10): void {
    const history = this.getDocumentHistory(documentId)
    if (history.versions.length <= keepCount) {
      return
    }

    // 保留最近的几个版本
    const recentVersions = history.versions.slice(-keepCount)
    history.versions = recentVersions
    this.store.set(`histories.${documentId}`, history)

    console.log(`Compressed versions for document ${documentId}, kept ${keepCount} recent versions`)
  }

  /**
   * 导出版本历史
   */
  public exportHistory(documentId: string): VersionHistory | null {
    return this.getDocumentHistory(documentId)
  }

  /**
   * 导入版本历史
   */
  public importHistory(history: VersionHistory): void {
    this.store.set(`histories.${history.documentId}`, history)
    console.log(`Imported history for document ${history.documentId}`)
  }

  /**
   * 清理所有旧版本
   */
  public cleanupAllVersions(): void {
    const histories = this.store.get('histories') as Record<string, VersionHistory>
    const documentIds = Object.keys(histories)

    documentIds.forEach(documentId => {
      const history = this.getDocumentHistory(documentId)
      this.cleanupOldVersions(history)
      this.store.set(`histories.${documentId}`, history)
    })

    console.log('Cleaned up old versions for all documents')
  }

  // 私有方法

  private calculateChecksum(content: string): string {
    // 简单的校验和计算
    let hash = 0
    for (let i = 0; i < content.length; i++) {
      const char = content.charCodeAt(i)
      hash = ((hash << 5) - hash) + char
      hash = hash & hash // 转换为32位整数
    }
    return hash.toString(16)
  }

  private cleanupOldVersions(history: VersionHistory): void {
    if (history.versions.length <= history.maxVersions) {
      return
    }

    // 删除最旧的版本，但保留当前版本
    const currentVersion = history.versions.find(v => v.id === history.currentVersion)
    const versionsToKeep = history.versions.slice(-history.maxVersions)

    if (currentVersion && !versionsToKeep.includes(currentVersion)) {
      // 如果当前版本被删除，添加回去
      versionsToKeep.push(currentVersion)
    }

    history.versions = versionsToKeep
  }

  private calculateDiff(from: string, to: string): Array<{
    type: 'add' | 'remove' | 'unchanged'
    content: string
    position: number
  }> {
    // 简单的行级差异计算
    const fromLines = from.split('\n')
    const toLines = to.split('\n')
    const diff: Array<{
      type: 'add' | 'remove' | 'unchanged'
      content: string
      position: number
    }> = []

    let i = 0, j = 0
    while (i < fromLines.length || j < toLines.length) {
      if (i >= fromLines.length) {
        // 只在目标文本中存在
        diff.push({
          type: 'add',
          content: toLines[j],
          position: j
        })
        j++
      } else if (j >= toLines.length) {
        // 只在源文本中存在
        diff.push({
          type: 'remove',
          content: fromLines[i],
          position: i
        })
        i++
      } else if (fromLines[i] === toLines[j]) {
        // 相同行
        diff.push({
          type: 'unchanged',
          content: fromLines[i],
          position: i
        })
        i++
        j++
      } else {
        // 不同行
        diff.push({
          type: 'remove',
          content: fromLines[i],
          position: i
        })
        diff.push({
          type: 'add',
          content: toLines[j],
          position: j
        })
        i++
        j++
      }
    }

    return diff
  }

  // 设置方法

  public setMaxVersionsPerDocument(max: number): void {
    this.maxVersionsPerDocument = max
    this.store.set('settings.maxVersionsPerDocument', max)
  }

  public setAutoSave(enabled: boolean): void {
    this.store.set('settings.autoSave', enabled)
  }

  public setCompressionThreshold(threshold: number): void {
    this.compressionThreshold = threshold
    this.store.set('settings.compressionThreshold', threshold)
  }

  public getSettings(): {
    maxVersionsPerDocument: number
    autoSave: boolean
    compressionThreshold: number
  } {
    return this.store.get('settings') as any
  }
}

// 导出单例实例
let versionManagerInstance: VersionManager | null = null

export function getVersionManager(): VersionManager {
  if (!versionManagerInstance) {
    versionManagerInstance = new VersionManager()
  }
  return versionManagerInstance
}